//
//  GLDrawable.m
//  LMPhotoVideoSDK
//
//  Created by Aimar on 16/7/19.
//  Copyright © 2016年 魁钺会. All rights reserved.
//

#import "GLDrawable.h"

@interface GLDrawable () {
    mat4      _transform;
}

@property (nonatomic, readonly, strong)NSMutableArray<GLDrawable*>*      drawables;

//Animation

@end

@implementation GLDrawable

- (id)init {
    self = [super init];
    if (self) {
        _drawables = [NSMutableArray arrayWithCapacity:10];
        self.scale = 1.0;
    }
    return self;
}

- (mat4*)transform {
    return &_transform;
}

- (void)onDraw:(GLCanvas*)canvas {
    if (canvas.effectShader == nil) {
        if (!self.shader.bind) {
            NSLog(@"bind shader fail! - %@", self);
        }
    } else {
        if (!canvas.effectShader.bind) {
            NSLog(@"bind shader fail! - %@", self);
        }
    }
    
    [self.shader setProjectionMatrix:[canvas projection]];
    [self.shader setModelViewMatrix:[canvas currentMatrix]];
    [self.shader setPosition:[self.surface getVertices] component:3];
    
    glDrawElements(GL_TRIANGLE_STRIP, [self.surface getIndexCount], GL_UNSIGNED_SHORT, [self.surface getIndices]);
}

- (void)draw:(GLCanvas*)canvas {
    [canvas save];
    Matrix4<float> tM = mat4::Translate(self.position.x, -self.position.y, self.position.z);
    Matrix4<float> rM = mat4::RotateZ(self.angle);
    Matrix4<float> sM = mat4::Scale(self.scale);
    Matrix4<float> m = tM * rM * sM;
    
    GLAnimation* am = self.animation;
    if (am != nil) {
        if (!am.initialized) {
            [am initializeWithSize:CGSizeMake(0, 0) parentSize:CGSizeMake(0, 0)];
        }
        
        Matrix4<float> aM;
        if([am getTransformation:CFAbsoluteTimeGetCurrent() * 1000 outTransform:&aM]) {
            m = aM * m;
        }
    }
    
    canvas.currentMatrix = m * canvas.currentMatrix;
    
    [self onDraw:canvas];
    
    NSInteger count = [self getDrawableCount];
    for (NSInteger i=0; i<count; ++i) {
        [canvas save];
        [[self getDrawableAt:i] draw:canvas];
        [canvas restore];
    }
    [canvas restore];
}

#pragma mark GLDrawableGroup
- (void)addDrawable:(GLDrawable*)drawable {
    [self.drawables addObject:drawable];
}

- (void)addDrawable:(GLDrawable*)drawable at:(NSInteger)index {
    [self.drawables insertObject:drawable atIndex:index];
}

- (NSInteger)getDrawableCount {
    return self.drawables.count;
}

- (NSInteger)indexOfDrawable:(GLDrawable*)drawable {
    return [self.drawables indexOfObject:drawable];
}

- (GLDrawable*)getDrawableAt:(NSInteger)index {
    return [self.drawables objectAtIndex:index];
}

- (void)removeDrawable:(GLDrawable*)drawable {
    [self.drawables removeObject:drawable];
}

- (void)removeDrawableAt:(NSInteger)index {
    [self.drawables removeObjectAtIndex:index];
}

- (void)removeAllDrawables {
    [self.drawables removeAllObjects];
}
@end
